package avicit.bdp.dgs.mdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.dgs.mdm.dao.MdataInterfaceDao;
import avicit.bdp.dgs.mdm.dao.MdataRInterfaceDao;
import avicit.bdp.dgs.mdm.dto.MdataInterfaceDTO;
import avicit.bdp.dgs.mdm.dto.MdataRInterfaceDTO;
import avicit.bdp.dgs.mdm.dto.TableDTO;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.exception.DaoException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.modules.system.syslog.service.SysLogUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @金航数码科技有限责任公司
 * @作者：${tableInfo.classCreator}
 * @邮箱：${tableInfo.classMailbox}
 * @创建时间： 2023-12-06 11:02
 * @类说明：
 * @修改记录：
 */
@Service
public class MdataRInterfaceService extends BaseService<MdataRInterfaceDao, MdataRInterfaceDTO> {

    private static final Logger logger = LoggerFactory.getLogger(MdataRInterfaceService.class);

    @Autowired
    private MdataRInterfaceDao mdataRInterfaceDao;
    @Autowired
    private MdataInterfaceDao mdataInterfaceDao;
    @Autowired
    private MdataInterfaceService mdataInterfaceService;
    @Autowired
    private TableService tableService;

    /**
     * 分页查询接口对应的主数据列表
     * @param interfaceId
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = true)
    public QueryRespBean<MdataRInterfaceDTO> getMDataPageList(String interfaceId, Integer pageNo, Integer pageSize)
            throws Exception {
        QueryRespBean<MdataRInterfaceDTO> queryRespBean = new QueryRespBean<>();
        PageHelper.startPage(pageNo, pageSize);
        Page<MdataRInterfaceDTO> pageList = mdataRInterfaceDao.getMDataPageList(interfaceId);
        queryRespBean.setResult(pageList);
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    /**
     * 新增对象
     *
     * @param dto 保存对象
     * @return String
     */
    @Transactional
    public String save(MdataRInterfaceDTO dto) {
        try {
            if(selectCountByNodeName(dto.getInterfaceId(), dto.getNodeName())){
                throw new BusinessException("数据挂载节点名称【"+dto.getNodeName()+"】重名");
            }
            if(selectCountByMdataId(dto.getInterfaceId(), dto.getMdataId())){
                throw new BusinessException("主数据【"+queryMdataNameById(dto.getMdataId())+"】已选择");
            }
            checkMdataId(dto);

            dto.setId(ComUtil.getId());
            PojoUtil.setSysProperties(dto, PlatformConstant.OpType.insert);
            this.insert(dto);
            // 记录日志
            SysLogUtil.log4Insert(dto);
            return dto.getId();
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 批量新增修改
     *
     * @param dtoList 保存对象
     * @return
     */
    @Transactional
    public void saveBatch(List<MdataRInterfaceDTO> dtoList) {
        if (CollectionUtils.isNotEmpty(dtoList)) {
            // 校验 数据挂载节点名称 和 主数据的唯一性
            for(MdataRInterfaceDTO dto : dtoList){
                if (StringUtils.isEmpty(dto.getId())) {
                    save(dto);
                }else{
                    update(dto);
                }
            }
        }
    }

    /**
     * 修改对象部分字段
     *
     * @param dto 修改对象
     * @return int
     */
    @Transactional
    public int update(MdataRInterfaceDTO dto) {
        try {
            MdataRInterfaceDTO oldDTO = this.selectByPrimaryKey(dto.getId());

            if(!oldDTO.getNodeName().equals(dto.getNodeName())){
                if(selectCountByNodeName(dto.getInterfaceId(), dto.getNodeName())){
                    throw new BusinessException("数据挂载节点名称【"+dto.getNodeName()+"】重名");
                }
            }

            if(!oldDTO.getMdataId().equals(dto.getMdataId())){
                if(selectCountByMdataId(dto.getInterfaceId(), dto.getMdataId())){
                    throw new BusinessException("主数据【"+queryMdataNameById(dto.getMdataId())+"】已选择");
                }
            }
            checkMdataId(dto);

            int count = this.updateByPrimaryKey(getUpdateDto(dto));
            if (count == 0) {
                throw new DaoException("数据失效，请重新更新");
            }
            return count;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 通过主键查询单条记录
     *
     * @param id 主键id
     */
    @Transactional(readOnly = true)
    public MdataRInterfaceDTO queryById(String id) {
        try {
            MdataRInterfaceDTO dto = this.selectByPrimaryKey(id);
            // 记录日志
            if (dto != null) {
                SysLogUtil.log4Query(dto);
            }
            return dto;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 删除
     */
    @Transactional
    public void deleteById(MdataRInterfaceDTO dto){
        if (StringUtils.isEmpty(dto.getId())) {
            throw new BusinessException("id不能为空");
        }

        String[] idArr = dto.getId().split(",");
        for(String id : idArr){
            this.deleteByPrimaryKey(id);
        }
    }

    /**
     * 内部方法，获取修改的dto对象
     *
     * @param dto
     * @return
     */
    private MdataRInterfaceDTO getUpdateDto(MdataRInterfaceDTO dto) {
        MdataRInterfaceDTO oldDTO = this.selectByPrimaryKey(dto.getId());
        if (oldDTO == null) {
            throw new DaoException("数据不存在");
        }
        //记录日志
        SysLogUtil.log4Update(dto, oldDTO);
        PojoUtil.setSysProperties(dto, PlatformConstant.OpType.update);
        PojoUtil.copyProperties(oldDTO, dto, true);
        return oldDTO;
    }

    /**
     * 查询主数据列表
     *
     */
    @Transactional(readOnly = true)
    public List<MdataRInterfaceDTO> queryList(String interfaceId) {
        MdataRInterfaceDTO dto = new MdataRInterfaceDTO();
        dto.setInterfaceId(interfaceId);
        return this.selectList(dto);
    }

    @Transactional(readOnly = true)
    public List<MdataRInterfaceDTO> queryList(String interfaceId, String mdataId) {
        MdataRInterfaceDTO dto = new MdataRInterfaceDTO();
        dto.setInterfaceId(interfaceId);
        dto.setMdataId(mdataId);
        return this.selectList(dto);
    }

    @Transactional(readOnly = true)
    public boolean selectCountByNodeName(String interfaceId, String nodeName) {
        MdataRInterfaceDTO dto = new MdataRInterfaceDTO();
        dto.setInterfaceId(interfaceId);
        dto.setNodeName(nodeName);
        return this.selectCount(dto) > 0;
    }

    @Transactional(readOnly = true)
    public boolean selectCountByMdataId(String interfaceId, String mdataId) {
        MdataRInterfaceDTO dto = new MdataRInterfaceDTO();
        dto.setInterfaceId(interfaceId);
        dto.setMdataId(mdataId);
        return this.selectCount(dto) > 0;
    }

    @Transactional(readOnly = true)
    public String queryMdataNameById(String mdataId) {
        TableDTO mdata = tableService.selectByPrimaryKey(mdataId);
        if(mdata != null){
            return mdata.getName();
        }
        return "";
    }

    @Transactional
    public void deleteMdataByInterfaceId(String interfaceId) {
        mdataRInterfaceDao.deleteMdataByInterfaceId(interfaceId);
    }

    /**
     * 验证同一个系统中，同一个主数据仅使用一次
     * @param dto
     */
    private void checkMdataId(MdataRInterfaceDTO dto){
        MdataInterfaceDTO mdataInterface = mdataInterfaceService.selectByPrimaryKey(dto.getInterfaceId());
        List<MdataInterfaceDTO> interfaceList = mdataInterfaceDao.selectByAppIdAndMdataId(mdataInterface.getApplicationId(), dto.getMdataId());
        if (CollectionUtils.isNotEmpty(interfaceList)) {
            throw new BusinessException("主数据【"+queryMdataNameById(dto.getMdataId())+"】已在接口【"+interfaceList.get(0).getName()+"】中选择");
        }
    }

}
